﻿using Apex.Commons.Extentions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using System.Net.Http.Headers;
using System.Text;

namespace Apex.Commons.Helper
{
    public class RequestHelper
    {
        private readonly IHttpClientFactory httpClientFactory;

        public RequestHelper(IHttpClientFactory httpClientFactory)
        {
            this.httpClientFactory = httpClientFactory;
        }

        /// <summary>
        /// 构建动态请求体
        /// </summary>
        /// <param name="parameters">字典</param>
        /// <returns></returns>
        public StringContent BuildBody(Dictionary<string, object> parameters)
        {
            // 将 Dictionary 对象序列化为 JSON 字符串
            var jsonContent = JsonConvert.SerializeObject(parameters);
            var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
            return content;
        }
        /// <summary>
        /// 构建动态请求体
        /// </summary>
        /// <typeparam name="T">泛型类</typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public StringContent BuildBody<T>(T t) where T : class
        {
            // 创建 HttpContent 对象
            var content = new StringContent(t.ToJsonString(true), Encoding.UTF8, "application/json");
            return content;
        }

        /// <summary>
        /// 解析返回值
        /// </summary>
        /// <returns></returns>
        public async Task<JObject> ParseReturnValueAsync(HttpResponseMessage response)
        {
            // 读取响应内容为字符串
            string responseBody = await response.Content.ReadAsStringAsync();
            // 解析 JSON 内容
            JObject json = JObject.Parse(responseBody);
            return json;
        }
        /// <summary>
        /// 将 HTTP 响应的内容流反序列化为指定类型的对象。
        /// 如果响应状态码不成功（非 2xx），抛出异常。
        /// </summary>
        /// <typeparam name="T">目标反序列化类型。</typeparam>
        /// <param name="response">HTTP 响应消息，包含需要反序列化的内容流。</param>
        /// <returns>反序列化后的对象实例。</returns>
        /// <exception cref="HttpRequestException">
        /// 当 <paramref name="response"/> 的 <see cref="HttpResponseMessage.IsSuccessStatusCode"/> 为 false 时抛出，
        /// 包含原始 HTTP 状态码信息。
        /// </exception>
        /// <exception cref="JsonException">
        /// 当 JSON 内容无法反序列化为目标类型 <typeparamref name="T"/> 时抛出。
        /// </exception>
        /// <remarks>
        /// 此方法会异步读取响应流，并使用 Newtonsoft.Json 进行反序列化。
        /// 注意：调用方需确保 <paramref name="response"/> 的 Content 不为 null。
        /// </remarks>
        /// <example>
        /// 示例用法：
        /// <code>
        /// var response = await httpClient.GetAsync("api/data");
        /// var data = await DeserializeAsync&lt;DataModel&gt;(response);
        /// </code>
        /// </example>
        public async Task<T> DeserializeAsync<T>(HttpResponseMessage response)
        {
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpRequestException($"HTTP error {response.StatusCode}");
            }

            using var stream = await response.Content.ReadAsStreamAsync();
            using var streamReader = new StreamReader(stream);
            using var jsonReader = new JsonTextReader(streamReader);

            return new JsonSerializer().Deserialize<T>(jsonReader);
        }
        /// <summary>
        /// post请求
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="project"></param>
        /// <param name="apiUrl"></param>
        /// <returns></returns>
        public async Task<T2?> PostHelperAsync<T1, T2>(T1 project, string apiUrl, AuthenticationHeaderValue? authenticationHeaderValue = null) where T1 : class
        {
            try
            {
                // 将 Project 对象序列化为 JSON 字符串
                string json = JsonConvert.SerializeObject(project);
                // 创建 HTTP 客户端
                var client = httpClientFactory.CreateClient();

                // 创建请求内容
                var content = BuildBody<T1>(project);

                if (authenticationHeaderValue != null)
                {
                    // 设置请求头，添加授权信息等，这里假设授权令牌的格式是 "Bearer <token>"，根据实际情况调整
                    client.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
                }

                // 发送 POST 请求
                HttpResponseMessage response = await client.PostAsync(apiUrl, content);

                // 解析返回值
                var returnVal = await DeserializeAsync<T2>(response);

                // 检查响应状态码
                if (response.IsSuccessStatusCode)
                {
                    Trace.TraceInformation("POST 请求成功发送到 API");
                }
                else
                {
                    Trace.TraceError($"POST 请求失败，状态码: {response.StatusCode}");
                }
                return returnVal;

            }
            catch (Exception ex)
            {
                Trace.TraceError($"发送 POST 请求时发生错误: {ex.Message}");
                return default;
            }
        }
    }
}
